package io.sundial.task;

import com.google.common.base.Joiner;
import com.google.common.base.Optional;

import java.io.Serializable;
import java.util.Collections;
import java.util.Date;

/**
 * 调度记录
 *
 * @author Payne 646742615@qq.com
 * 2018/12/29 10:45
 */
public class Scheduling implements Serializable {
    private static final long serialVersionUID = -2879719843926493745L;

    private String taskName;
    private String taskGroup;
    private String cronExpression;
    private String description;
    private Integer shardingTotal;
    private String shardingTable;
    private String balanceAlgorithm;
    private String misfireInstruction;
    private Boolean concurrentAllowed;
    private Date dateStart;
    private Date dateEnd;
    private Integer priority;
    private String jobName;
    private String jobGroup;
    private String jobArguments;

    private Long time;
    private String schedulerName;
    private Boolean finished;

    private Date dateCreated;
    private Date lastUpdated;
    private Integer version;

    public Scheduling() {
    }

    public Scheduling(Scheduling.Key key) {
        this.taskName = key.taskName;
        this.taskGroup = key.taskGroup;

        this.time = key.time;
    }

    public Scheduling(Task task, long time, String schedulerName) {
        this.taskName = task.getName();
        this.taskGroup = task.getGroup();
        this.cronExpression = task.getCronExpression();
        this.description = task.getDescription();
        this.shardingTotal = task.getShardingTotal();
        this.shardingTable = task.getShardingTable();
        this.balanceAlgorithm = task.getBalanceAlgorithm();
        this.misfireInstruction = task.getMisfireInstruction();
        this.concurrentAllowed = task.isConcurrentAllowed();
        this.dateStart = task.getDateStart();
        this.dateEnd = task.getDateEnd();
        this.priority = task.getPriority();
        this.jobName = task.getJobName();
        this.jobGroup = task.getJobGroup();
        this.jobArguments = Joiner.on("&")
                .withKeyValueSeparator("=")
                .join(Optional.fromNullable(task.getJobArguments()).or(Collections.<String, String>emptyMap()));

        this.time = time;
        this.schedulerName = schedulerName;
        this.finished = false;
    }

    public static class Key implements Serializable {
        private static final long serialVersionUID = 3476162414913639500L;

        private final String taskName;
        private final String taskGroup;

        private final Long time;

        public Key(String taskName, String taskGroup, Long time) {
            this.taskName = taskName;
            this.taskGroup = taskGroup;
            this.time = time;
        }

        public String getTaskName() {
            return taskName;
        }

        public String getTaskGroup() {
            return taskGroup;
        }

        public long getTime() {
            return time;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Key key = (Key) o;

            if (taskName != null ? !taskName.equals(key.taskName) : key.taskName != null) return false;
            if (taskGroup != null ? !taskGroup.equals(key.taskGroup) : key.taskGroup != null) return false;
            return time != null ? time.equals(key.time) : key.time == null;
        }

        @Override
        public int hashCode() {
            int result = taskName != null ? taskName.hashCode() : 0;
            result = 31 * result + (taskGroup != null ? taskGroup.hashCode() : 0);
            result = 31 * result + (time != null ? time.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "/" + taskGroup + "/" + taskName + "/" + time;
        }
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String name) {
        this.taskName = name;
    }

    public String getTaskGroup() {
        return taskGroup;
    }

    public void setTaskGroup(String group) {
        this.taskGroup = group;
    }

    public String getCronExpression() {
        return cronExpression;
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getShardingTotal() {
        return shardingTotal;
    }

    public void setShardingTotal(Integer shardingTotal) {
        this.shardingTotal = shardingTotal;
    }

    public String getShardingTable() {
        return shardingTable;
    }

    public void setShardingTable(String shardingTable) {
        this.shardingTable = shardingTable;
    }

    public String getBalanceAlgorithm() {
        return balanceAlgorithm;
    }

    public void setBalanceAlgorithm(String balanceAlgorithm) {
        this.balanceAlgorithm = balanceAlgorithm;
    }

    public String getMisfireInstruction() {
        return misfireInstruction;
    }

    public void setMisfireInstruction(String misfireInstruction) {
        this.misfireInstruction = misfireInstruction;
    }

    public Boolean getConcurrentAllowed() {
        return concurrentAllowed;
    }

    public void setConcurrentAllowed(Boolean concurrentAllowed) {
        this.concurrentAllowed = concurrentAllowed;
    }

    public Date getDateStart() {
        return dateStart;
    }

    public void setDateStart(Date dateStart) {
        this.dateStart = dateStart;
    }

    public Date getDateEnd() {
        return dateEnd;
    }

    public void setDateEnd(Date dateEnd) {
        this.dateEnd = dateEnd;
    }

    public Integer getPriority() {
        return priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getJobGroup() {
        return jobGroup;
    }

    public void setJobGroup(String jobGroup) {
        this.jobGroup = jobGroup;
    }

    public String getJobArguments() {
        return jobArguments;
    }

    public void setJobArguments(String jobArguments) {
        this.jobArguments = jobArguments;
    }

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    public String getSchedulerName() {
        return schedulerName;
    }

    public void setSchedulerName(String schedulerName) {
        this.schedulerName = schedulerName;
    }

    public Boolean getFinished() {
        return finished;
    }

    public void setFinished(Boolean finished) {
        this.finished = finished;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }

    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Scheduling that = (Scheduling) o;

        if (taskName != null ? !taskName.equals(that.taskName) : that.taskName != null) return false;
        if (taskGroup != null ? !taskGroup.equals(that.taskGroup) : that.taskGroup != null) return false;
        return time != null ? time.equals(that.time) : that.time == null;
    }

    @Override
    public int hashCode() {
        int result = taskName != null ? taskName.hashCode() : 0;
        result = 31 * result + (taskGroup != null ? taskGroup.hashCode() : 0);
        result = 31 * result + (time != null ? time.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "/" + taskGroup + "/" + taskName + "/" + time;
    }
}
